require "Common/define"
require "Logic/Config"
require "Common/functions"

UIClimbTower = {};
HelperFunc.SetUIEnv(UIClimbTower)
local this = UIClimbTower

this._mwclPlayTime = 3000 -- 爬塔入场动画持续时间（毫秒）
this.gameObject = nil;
this.transform = nil;
this.LuaBehaviour = nil;
this.canClickChallenge = true;

this.levelName = nil;
this.levelList = nil;
this.btn_challenge = nil;
this.btn_introduce = nil;
this.btn_reward = nil;
this.btn_record = nil;
this.btn_sort = nil;
this.btn_back = nil;
this.climbTowerReward = nil;
this.rewardList = nil;
this.btnClose = nil;
this.tipController = nil;
this.challengeController = nil;
this.btnRewardClose = nil;
this.desc = nil;
this.rewardName = nil;
this.mainlevelName = nil;
this.recordName = nil;
this.sortName = nil;
this.minTowerlevel = nil;

this.curTowerlevel = nil;
this.tablevel = {};
this.curTowerInfo = {};
this.enemyPos = {};
this.Roles = {};
this.drawWrappers = {};
this.roleScale = { 115, 125, 110, 120, 130, 110 }--英雄大小1号位至6号位
this.towerType = nil;
this.listReward = nil;
this.listRewardText = nil;
this.listRewardCount = 0;
this.hugeRewardCtrl = nil;
this.mainReward = nil

function UIClimbTower.Init(fun, _showPrefabIn, towerType)
    UIClimbTower.showPrefabIn = _showPrefabIn;
    this.towerType = towerType or 1
    this.cfg_tower_type_item = G.dataTable["t_towertype"][tostring(this.towerType)]
    logicMgr.TowerManager.setClimbType(this.towerType)
    local name, packageName = getUIName(PanelNames.UIClimbTower);
    panelMgr:Push(name, packageName, this.onCreate, Config.useLocalUI);
end

function UIClimbTower.onCreate(obj)
    if not this.hasInit then
        this.hasInit = true
        mainlevelName = obj:GetChild("levelName"):GetChild("title")
        rewardName = obj:GetChild("btn_reward")
        recordName = obj:GetChild("btn_record")
        sortName = obj:GetChild("btn_sort")
        group_OccupationTip = obj:GetChild("OccupationTipGroup")
        OccupationLimitCtrl = obj:GetController("towerpro")
        this.MaxLevel = obj:GetController("MaxLevel")
        this.mainReward = obj:GetChild("mainReward")
        btn_challenge = obj:GetChild("btn_challenge");
        btn_introduce = obj:GetChild("btn_introduce");
        btn_reward = obj:GetChild("btn_reward");
        btn_record = obj:GetChild("btn_record");
        btn_sort = obj:GetChild("btn_sort");
        btn_back = obj:GetChild("btn_back");
        Com_Floor = obj:GetChild("Com_Floor");
        aniSwitch = Com_Floor:GetTransition("t1");
        aniRevert = Com_Floor:GetTransition("t2");
        this.title = obj:GetChild("title");
        this.listReward = obj:GetChild("listReward");
        this.hugeRewardCtrl = obj:GetController("hugeReward");
        this.listRewardText = obj:GetChild("text");

        this.levelList = {}
        for i = 1, 10 do
            table.insert(this.levelList, Com_Floor:GetChild("Btn_Floor" .. i))
        end
        challengeController = obj:GetController("btnChallenge")
        climbTowerReward = obj:GetChild("climbTowerReward")
        rewardList = climbTowerReward:GetChild("rewardList")
        desc = climbTowerReward:GetChild("text")
        this.mask = obj:GetChild("mask")
        this.UI_ruchang_mwcl_in = obj:GetChild("UI_ruchang_mwcl_in")
        this.mask.visible = false
        this.enemyPos = {}
        for i = 1, 6 do
            local role = obj:GetChild("enemy" .. i)
            table.insert(this.enemyPos, role)
        end
        this.addEvent();
        if not logicMgr.TowerManager.getPlayStart() then
            towerHandler.sendGetTowerInfo()
            logicMgr.TowerManager.setPlayStart(true)
        end
    end
    if this.showPrefabIn then
        this.showPrefabIn = nil;
        resMgr:LoadModelPrefab("UIEff/UI_ruchang_mwcl_in", function(prefab)
            if prefab then
                if this.effDrawWrapper == nil then
                    this.effDrawWrapper = GoWrapper.New();
                end
                if this.effObj ~= nil then
                    destroyImmediate(this.effObj);
                end
                this.effObj = newObject(prefab)
                this.effDrawWrapper:SetWrapTarget(this.effObj,false)
                Util.Lua_SetLocalRotationXYZ(this.effObj.transform, 0, 0, 0);
                this.UI_ruchang_mwcl_in:SetNativeObject(this.effDrawWrapper)
            end
        end)
    end
    this.lastItem = nil
    this.enemyNum = 0
    this.initUI()
    if logicMgr.TowerManager.showUIBattleTeamImmediate then
        logicMgr.TowerManager.showUIBattleTeamImmediate = false
        this.DoClickChallenge()
    end
    if this.towerType > 1 then
        logicMgr.FuncOpenManager.refreshMainReward(this.mainReward,Config.FuncOpenType.TowerAdvaced)
    else
        logicMgr.FuncOpenManager.refreshMainReward(this.mainReward,Config.FuncOpenType.Tower)
    end
end

function UIClimbTower.OnEnable()
    AudioManager.SetSwitch("battle_steps", "arr")
    FightManager.SetBGMSwitchByBattleType(EnumConst.FightTypeConst.TOWER)
    AudioManager.SetSwitch("Battle_SwitchGroup", "corridor")
    this.LocalListenEvent()
    logicMgr.TowerManager.enterTower()
    this.needShowHeadMenu = nil
    if isOpenUI(PanelNames.UIHeadMenu) then
        this.needShowHeadMenu = true
        closeUI(PanelNames.UIHeadMenu)
    end
end

function UIClimbTower.OnDisable() 
    this.LocalCloseEvent()
    this.closeEnemyFormation()
end

function UIClimbTower.OnDestroy()
    this.hasInit = nil
    this.removeEvent()
    this.LocalCloseEvent()
    this.closeEnemyFormation()
end

function UIClimbTower.LocalListenEvent()
    ListenEvent(Config.EventType.Fresh_Tower, this.initUI)
    ListenEvent(Config.EventType.Fresh_AdvancedTower, this.SkipOneDay)
end

function UIClimbTower.LocalCloseEvent()
    CloseEvent(Config.EventType.Fresh_Tower, this.initUI)
    CloseEvent(Config.EventType.Fresh_AdvancedTower, this.SkipOneDay)
end

function UIClimbTower.addEvent()
    btn_challenge.onClick:Add(this.onClickChallenge)
    btn_introduce.onClick:Add(this.onClickShowIntroduce)
    btn_reward.onClick:Add(this.onClickShowReward)
    btn_record.onClick:Add(this.onClickShowRecord)
    btn_sort.onClick:Add(this.onClickShowRank)
    btn_back.onClick:Add(this.onClickBack)
end


function UIClimbTower.removeEvent()
    btn_challenge.onClick:Remove(this.onClickChallenge)
    btn_introduce.onClick:Remove(this.onClickShowIntroduce)
    btn_reward.onClick:Remove(this.onClickShowReward)
    btn_record.onClick:Remove(this.onClickShowRecord)
    btn_sort.onClick:Remove(this.onClickShowRank)
    btn_back.onClick:Remove(this.onClickBack)
end

function UIClimbTower.initUI()
    rewardName.title = getLanguage("Sys_TowerBtn_Reward")
    recordName.title = getLanguage("Sys_TowerBtn_Record")
    sortName.title = getLanguage("Sys_TowerBtn_Rank")
    local showOccupationTip = this.cfg_tower_type_item["f_Group"] == EnumConst.TowerType.Advanced
    group_OccupationTip.visible = showOccupationTip
    if this.cfg_tower_type_item["f_Group"] == EnumConst.TowerType.Advanced then
        OccupationLimitCtrl.selectedIndex = this.towerType - 2
    end
    curTowerInfo = logicMgr.TowerManager.returnTowerInfo(this.towerType);
    --初始当前层级
    this.curTowerlevel = tonumber(curTowerInfo["layerId"]);
    this.lastTowerlevel = tonumber(logicMgr.TowerManager.getLastLayerId(this.towerType));
    logicMgr.TowerManager.setLastLayerId(this.towerType);
    this.hugeRewardCtrl.selectedIndex = 1;
    this.listRewardCount = 0;
    --curTowerlevel = nil; -- 策划要求,通关敌人死亡效果不要了,先暂时屏蔽,防止后面再加回来
    if this.lastTowerlevel == nil or math.ceil(this.lastTowerlevel/5) == math.ceil(this.curTowerlevel/5) then
        aniRevert:Play()
        this.lastTowerlevel = curTowerlevel
        if not this.isShowTurn then
            this.refreshUI();
        end
        this.isShowClouding = false;
        this.isShowTurn = false
        if curTowerlevel ~= nil and curTowerlevel % 5 ~= 0 then
            this.hugeRewardCtrl.selectedIndex = 0;
        end
        this.listRewardCount = 1;
		this.listReward.visible = true;
        --根据英雄爬塔等级拿数据
    else
        this.isShowTurn = true
        this.mask.visible = true;
        this.refreshUI();
        this.canClickChallenge = false;
        aniSwitch:Play(function()
            this.canClickChallenge = true;
            this.initUI();
            this.mask.visible = false;
            this.hugeRewardCtrl.selectedIndex = 0;
			this.listReward.visible = true
        end)
    end
    this.title.text = string.format("第%d层", curTowerlevel);
    local minlevel = math.floor((this.lastTowerlevel - 1) / 5) * 5 + 1;
    minTowerlevel = minlevel;
    local maxlevel = minlevel + 9;
    -- local index = 6;
    for i = minlevel, maxlevel, 1 do
        local item = this.levelList[i - minlevel + 1];
        this.setHeadIcon(item:GetChild("player"));
        local playerController = item:GetController("player");
        playerController.selectedIndex = 0;
        if i >= tonumber(curTowerlevel) then
            item.enabled = true
            item.title = i;
            if i == tonumber(curTowerlevel) then
                playerController.selectedIndex = 1;
                item:GetTransition("back"):Play();
                item.selected = true;
                this.lastItem = item;
            end
        elseif i < tonumber(curTowerlevel) then
            item.enabled = false
            item.title = getLanguage("ClimbTowerTips1");
        end
        item.onClick:Clear();
        item.onClick:Add(function()
            this.recordLevel(i);
        end);
        this.showSpecialReward(i);
    end
    if this.isShowClouding then
        logicMgr.TowerManager.setLastLayerId(this.towerType)
        local transition = this.lastItem:GetTransition("move" .. curTowerlevel % 5 % 2)
        transition:Play()
        utimer.timeCall(function()
            this.initUI();
            this.mask.visible = false;
        end, 1000, 1);
    end
end

function UIClimbTower.showSpecialReward(towerLevel)
    if towerLevel % 5 == 0 then
        local specialReward = logicMgr.TowerManager.getSpecialReward(this.towerType, towerLevel);
        if specialReward ~= nil then
            if this.listRewardCount == 1 then
                this.listReward:RemoveChildrenToPool();
                local ctrlItem = CtrlManager.GetCtrl(PanelNames.Item);
                local reward = decodeJsonStrToTabel(specialReward);
                if reward ~= nil then
                    for i = 1, #reward do
                        local rewardInfo = logicMgr.CostManager.getItemOrEquipDataByIdAndNum(reward[i][1], reward[i][2], {isShowBigNum = true});
                        local rewardObj = this.listReward:AddItemFromPool()
                        if ctrlItem ~= nil then
                            ctrlItem.initData(rewardObj, rewardInfo);
                        end
                    end
                else
                    this.hugeRewardCtrl.selectedIndex = 0;
                end

                this.listRewardText.text = string.format(getLanguage("ClimbTowerTips16"), towerLevel);
            end
            this.listRewardCount = this.listRewardCount + 1;
        end
    end
end

function UIClimbTower.setHeadIcon(obj)
    obj:GetChild("head"):GetChild("HeadIcon").url = logicMgr.HeroManager.GetRoleIcon()
    local frameId = logicMgr.HeroManager.GetRoleInfo("picFrame")
    obj:GetChild("frame").url = "ui://ICONAtlas/" .. frameId;
end

--记录当前选择的塔层级
function UIClimbTower.recordLevel(level)
    if curTowerlevel == level then return end
    curTowerlevel = level
    this.title.text = string.format("第%d层", curTowerlevel)
    if level % 5 ~= 0 then
        this.hugeRewardCtrl.selectedIndex = 0
    else
        this.hugeRewardCtrl.selectedIndex = 1
    end
    this.refreshUI()
end

function UIClimbTower.refreshUI()
    local towerInfo = logicMgr.TowerManager.returnTowerInfo(this.towerType)
    local towerLayer = towerInfo["layerId"]
    if challengeController ~= nil then
        if tonumber(towerLayer) ~= tonumber(curTowerlevel) then
            challengeController.selectedIndex = 0
        else
            challengeController.selectedIndex = 1
        end 
    end  
    if mainlevelName ~= nil then
        mainlevelName.text = getLanguage(this.cfg_tower_type_item["f_TitelText"])
    end

    this.updateEnemyFormation(this.towerType, curTowerlevel)
    this.ShowCurReward()
end
function UIClimbTower.DoClickChallenge()
    if #this.OppoFormation == 0 then
        UISysTips.AddMsg(getLanguage("ErrorCode_5001"));
        return
    end
    local towerInfo = logicMgr.TowerManager.returnTowerInfo(this.towerType)
    local towerLayer = towerInfo["layerId"];
    local curTowerGroup = this.cfg_tower_type_item["f_Group"] or 1
    local curTowerLimit = this.cfg_tower_type_item["f_limit"] or 1
    if curTowerGroup == EnumConst.TowerType.Advanced and towerInfo.todayLayer >= curTowerLimit then
        UISysTips.AddMsg(getLanguage("ClimbTowerTips15"));
        return
    end

    if tonumber(towerLayer) == tonumber(curTowerlevel) then
        BattleScene.stop();
        showUI(PanelNames.UIBattleTeam, EnumConst.FightTypeConst.TOWER, nil, function(formations)
            --点击迷雾长廊【战斗】按钮
            local _towerDic = {}
            _towerDic.tower_stage_id = tostring((this.towerType - 1)*10000 + curTowerlevel)
            TAManager.TrackByDictionary("tower_click_challenge", _towerDic)

            towerHandler.sendTowerBoss(this.towerType, curTowerlevel, formations[1]);
            this.closeEnemyFormation();
        end);
    end
end
--挑战（通过当前关卡才能挑战下一关）
function UIClimbTower.onClickChallenge()
    if not this.canClickChallenge then return end
    this.DoClickChallenge()
end

--说明
function UIClimbTower.onClickShowIntroduce()
    local txts = {};
    if this.towerType == EnumConst.TowerType.NORMAL then
        txts["des"] = "HelpDes3";
        txts["title"] = "HelpTitle3";
        txts["story"] = "FunctionStory303";
    else
        txts["des"] = "HelpDes301";
        txts["title"] = "HelpTitle301";
        txts["story"] = "FunctionStory613";
    end
    showUI(PanelNames.CommonTips, txts);
end

--预览奖励
function UIClimbTower.onClickShowReward()
    local towerInfo = logicMgr.TowerManager.returnTowerInfo(this.towerType);
    local towerLayer = tonumber(towerInfo["layerId"]);
    showUI(PanelNames.UIClimbTowerReward, towerLayer)
end

--当前层级奖励
function UIClimbTower.ShowCurReward()
    --tipController.selectedIndex = 1;
    rewardList:RemoveChildrenToPool();
    --levelName:GetChild("title2").text = string.format(getLanguage("Sys_TowerReward"), curTowerlevel);
    desc.text = getLanguage("Sys_TowerRewardDes");

    local rewardsData = logicMgr.TowerManager.returnReward(this.towerType, curTowerlevel);
    local ctrlItem = CtrlManager.GetCtrl(PanelNames.Item);
    for i = 1, #rewardsData do
        local rewardObj = rewardList:AddItemFromPool()
        if ctrlItem ~= nil then
            --初始装备信息
            ctrlItem.initData(rewardObj, rewardsData[i]);
        end
    end
    rewardList:ResizeToFit()
end

--通关记录
function UIClimbTower.onClickShowRecord()
    showUI(PanelNames.UIClimbTowerRecord,curTowerlevel, this.towerType)
end

function UIClimbTower.onShowRecord(playerDataList)
    local recordData = {};
    recordData["curTowerLevel"] = curTowerlevel;
    if playerDataList ~= nil and #playerDataList > 0 then
        recordData["playerDataList"] = playerDataList;
    end
end

--排行耪
function UIClimbTower.onClickShowRank()
    showUI(PanelNames.UIClimbTowerSort, this.towerType)
end

function UIClimbTower.onClickBack()
    if this.effObj ~= nil then
        destroyImmediate(this.effObj);
        this.effObj = nil;
    end
    this.closeEnemyFormation();
    closeUI(PanelNames.UIClimbTower);
    if this.needShowHeadMenu then
        showUI(PanelNames.UIHeadMenu);
        this.needShowHeadMenu = nil;
    end
end

function UIClimbTower.closeEnemyFormation()
    if this.OppoFormation == nil then return end    for i = 1, #this.OppoFormation do
        local Role = this.Roles[i];
        if (Role ~= nil) then
            destroyImmediate(Role);
            this.Roles[i] = nil;
        end
        if this.drawWrappers[i] then
            this.drawWrappers[i]:Dispose()
            this.drawWrappers[i] = nil;
        end
    end
end

function UIClimbTower.updateEnemyFormation(type, id)
    this.setEnemyFormation(type, id)
    this.enemyNum = 0
    for i = 1, #this.OppoFormation do
        local role = this.enemyPos[i]
        local itemData = this.OppoFormation[i]
        this.enemyNum = this.enemyNum + 1
        this.initEnemy(role, itemData, i)
    end
end

function UIClimbTower.setEnemyFormation(type, id)
    local teamInfo = this.getTowerMonsterTeam(type, id)
    this.OppoFormation = {}
    if teamInfo ~= nil then
        this.MaxLevel.selectedIndex = 0
        for k, v in pairs(teamInfo.team) do
            this.OppoFormation[k] = {}
            this.OppoFormation[k]["partnerId"] = v[1]
            this.OppoFormation[k]["partnerModelId"] = v[1]
            this.OppoFormation[k]["level"] = v[2]
            this.OppoFormation[k]["star"] = v[4]
            this.OppoFormation[k]["icon"] = ""
            this.OppoFormation[k]["teamIndex"] = 2
        end
    else
        this.MaxLevel.selectedIndex = 1;
    end
end

function UIClimbTower.getTowerMonsterTeam(type, id)
    local towerCg = G.dataTable["t_tower"][tostring((type-1)*10000+id)];
    if towerCg == nil then
        return nil;
    end
    local teamCg = dataTable.getDataTableByStringId("t_towermonsterteam",towerCg.f_TowerMonsterTeamId);

    local info = {};
    info["stactics"] = teamCg.f_TacticsId_Id;
    info["team"] = {};
    for i = 1, 6 do
        local monster = decodeJsonStrToTabel(teamCg["f_MonsterPara" .. i]);
        table.insert(info["team"], monster);
    end
    return info;
end

function UIClimbTower.initEnemy(obj, data, index)
    local url = HeroManager.GetHeroDrawingRolePath(data.partnerModelId)
    resMgr:LoadModelPrefab(url, function(go)
        local Role = this.Roles[index];
        local drawWrapper = this.drawWrappers[index];
        if drawWrapper == nil then
            drawWrapper = GoWrapper.New();
            this.drawWrappers[index] = drawWrapper;
        end
        if (Role ~= nil) then
            destroyImmediate(this.Roles[index]);
        end
        Role = newObject(go);
        this.Roles[index] = Role;
        Role:SetActive(true)
        Role.name = url;
        Role:AddComponent(TCanvas);
        Role:AddComponent(TChangeSortingOrder);
        local aniObj = Role.transform:Find("Animation").gameObject
        if this.isShowClouding then
            Util.PlayAction(aniObj, "death", true, 4)
        else
            Util.PlayAction(aniObj, "fidle", true, 4)
        end
 
        logicMgr.EquipManager.setWeaponSkin(aniObj, data.partnerModelId, false);
        drawWrapper:SetWrapTarget(Role, true)
        Util.Lua_SetLocalPositionXYZ(Role.transform, 0, 0, 0)
        Util.Lua_SetLocalRotationXYZ(aniObj.transform, 0, 0, 0)
        Util.Lua_SetLocalScaleXYZ(aniObj.transform, -this.roleScale[index], this.roleScale[index], this.roleScale[index])
        obj:GetChild("ModelPos"):SetNativeObject(drawWrapper);
        obj:GetChild("level").text = string.format(getLanguage("Level"), data.level) --.."级" ;
        this.enemyNum = this.enemyNum - 1;
        if this.enemyNum <= 0 then
            utimer.timeCall(HelperFunc.CloseUILoading, 300, 1);
        end
    end)
end
function UIClimbTower.SkipOneDay()
    if this.cfg_tower_type_item["f_Group"] == EnumConst.TowerType.Advanced then
        this.onClickBack();
    end
end

return UIClimbTower;